package com.tul.vapp.servicecenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.tul.cusa.common.util.DateUtil;
import com.tul.cusa.common.util.StringUtil;
import com.tul.cusa.container.jetty.MQBroker;
import com.tul.vapp.servicecenter.bean.EmsConfig;
import com.tul.vapp.servicecenter.bean.VappCmdBean;
import com.tul.vapp.servicecenter.dao.IAppDao;
import com.tul.vapp.servicecenter.entity.Item;
import com.tul.vapp.servicecenter.entity.Namespace;
import com.tul.vapp.servicecenter.entity.Status;
import com.tul.vapp.servicecenter.service.IEmsProxyService;
import com.tul.vapp.servicecenter.service.IItemService;
import com.tul.vapp.servicecenter.service.IManager;
import com.tul.vapp.servicecenter.service.INamespaceService;
import com.tul.vapp.servicecenter.service.IZkService;
import com.tul.vapp.servicecenter.util.SysConfigUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * EMS配置
 * <p>
 * <pre>
 * mongodb.name=ems-proxy1
 * dubbo.protocol.ip=127.0.0.1
 * dubbo.port=54351
 * ems.id=10000
 * ems.name=EMS代理1
 * u2000.servicename=fiberhome
 * u2000.ip=10.170.120.31
 * u2000.port=52001
 * u2000.name=admin
 * u2000.pwd=admin
 * </pre>
 *
 * @author wwxiang
 * @author wangziang
 * @since 2018/1/16.
 */
@Service
public class EmsProxyService implements IEmsProxyService {

    private static final String EMS_APP_ID = "ems-proxy";
    private static final String GLOBAL_APP_ID = "global";
    private static final String COMMON = "common.properties";
    private static final String EMS_IP = "dubbo.protocol.ip";
    private static final String EMS_PORT = "dubbo.port";
    private static final String MONGODB_NAME = "mongodb.name";
    private static final String EMS_ID = "ems.id";
    private static final String EMS_NAME = "ems.name";
    private static final String U2K_SERVICENAME = "u2000.servicename";
    private static final String U2K_IP = "u2000.ip";
    private static final String U2K_PORT = "u2000.port";
    private static final String U2K_NAME = "u2000.name";
    private static final String U2K_PWD = "u2000.pwd";


    private static Pattern pattern = Pattern.compile("ems");
    /**
     * manager
     */
    @Autowired
    private IManager manager;
    @Autowired
    private IZkService zkService;
    @Autowired
    private INamespaceService namespaceService;
    @Autowired
    private IAppDao appDao;
    @Autowired
    private IItemService itemService;
    private MQBroker broker = new MQBroker(SysConfigUtil.getProperty("mq.client"));

    @Override
    public List<EmsConfig> getEmsConfigs() {
        List<EmsConfig> configs = new ArrayList();
        List<Namespace> ns = namespaceService.getNamespaces();
        for (Namespace n : ns) {
            if (!pattern.matcher(n.getNamespace()).lookingAt()) {
                continue;
            }
            // 找出所有的emsX.properties空间，将其转换为EmsConfig
            EmsConfig config = getEmsConfig(n.getNamespace());
            configs.add(config);
        }
        return configs;
    }

    @Override
    public boolean updateEmsConfig(EmsConfig emsConfig) {
        int emsIndex = Integer.parseInt(emsConfig.getEmsId()) - 9999;
        String namespace = "ems" + emsIndex + ".properties";
        Namespace emsNamespace = namespaceService.getNamespace(EMS_APP_ID, namespace);
        emsNamespace.setStatus(Status.MODIFY);
		namespaceService.updateNamespace(emsNamespace);
		itemService.update(EMS_APP_ID, namespace, MONGODB_NAME, "ems-proxy" + emsIndex);
		itemService.update(EMS_APP_ID, namespace, EMS_IP, emsConfig.getEmsIp());
        itemService.update(EMS_APP_ID, namespace, EMS_PORT, String.valueOf(emsConfig.getEmsPort()));
        itemService.update(EMS_APP_ID, namespace, EMS_NAME, emsConfig.getEmsName());
        itemService.update(EMS_APP_ID, namespace, U2K_IP, emsConfig.getU2kIp());
        itemService.update(EMS_APP_ID, namespace, U2K_PORT, String.valueOf(emsConfig.getU2kPort()));
        itemService.update(EMS_APP_ID, namespace, U2K_NAME, emsConfig.getU2kName());
        itemService.update(EMS_APP_ID, namespace, U2K_PWD, emsConfig.getU2kPwd());
        return true;
    }

    @Override
    public boolean syncEms(int emsId) {
        VappCmdBean cmd = new VappCmdBean();
        cmd.setCmd("emsSync");
        String appName = "ems" + (emsId - 9999);
        cmd.setAppName(appName);
        broker.sendTopic("vapp_cmd", JSON.toJSONString(cmd));
        return true;
    }

    @Override
    public boolean deleteEmsConfig(int emsId) {
        int emsIndex = emsId - 9999;
        String namespace = "ems" + emsIndex + ".properties";
        //同时删除命名空间和下面的items
        namespaceService.deleteCascade(EMS_APP_ID, namespace);
        zkService.deleteNamespace(EMS_APP_ID, namespace);
        return true;
    }

    @Override
    public boolean addEmsConfig(EmsConfig emsConfig) {
        int emsIndex = Integer.parseInt(emsConfig.getEmsId()) - 9999;
        String namespace = "ems" + emsIndex + ".properties";
        Namespace namespaceBean = new Namespace();
        String date = DateUtil.format(new Date(), DateUtil.DATE_TIME_FORMAT);
        namespaceBean.setCreateTime(date);
        namespaceBean.setStatus(Status.INSERT);
        namespaceBean.setNamespace(namespace);
        namespaceBean.setAppId(EMS_APP_ID);
        namespaceService.addNamespace(namespaceBean);

		itemService.addItem(EMS_APP_ID, namespace, MONGODB_NAME, "ems-proxy" + emsIndex);
		itemService.addItem(EMS_APP_ID, namespace, EMS_ID, emsConfig.getEmsId());
        itemService.addItem(EMS_APP_ID, namespace, EMS_IP, emsConfig.getEmsIp());
        itemService.addItem(EMS_APP_ID, namespace, EMS_PORT, String.valueOf(emsConfig.getEmsPort()));
        itemService.addItem(EMS_APP_ID, namespace, EMS_NAME, emsConfig.getEmsName());
        itemService.addItem(EMS_APP_ID, namespace, U2K_IP, emsConfig.getU2kIp());
        itemService.addItem(EMS_APP_ID, namespace, U2K_PORT, String.valueOf(emsConfig.getU2kPort()));
        itemService.addItem(EMS_APP_ID, namespace, U2K_NAME, emsConfig.getU2kName());
        itemService.addItem(EMS_APP_ID, namespace, U2K_PWD, emsConfig.getU2kPwd());
        return true;
    }

    @Override
    public boolean publishEms() {
        List<Namespace> ns = namespaceService.getNamespaces();
        for (Namespace n : ns) {
            if (!pattern.matcher(n.getNamespace()).lookingAt()) {
                continue;
            }
            manager.publish(EMS_APP_ID, n.getNamespace());
        }
        return true;
    }

	/**
     *  找出所有的emsX.properties空间，将其转换为EmsConfig
     * @param namespace 命名空间
     * @return EmsConfig
     */
    private EmsConfig getEmsConfig(String namespace) {
        EmsConfig config = new EmsConfig();
        List<Item> items = itemService.getItems(EMS_APP_ID, namespace);
        for (Item item : items) {
            handleEachItem(item, config);
        }
        //设置aid
        config.setAid(appDao.getApp(EMS_APP_ID).getId());
        config.setStatus(namespaceService.getNamespace(EMS_APP_ID, namespace).getStatus());
        //设置发布状态
        if (namespaceService.getNamespace(EMS_APP_ID, namespace).getStatus() == Status.PUBLISHED) {
            config.setRelease(true);
        } else {
            config.setRelease(false);
        }
        return config;
    }

	/**
     * 处理每个item
     * @param item 每个配置项
     * @param config EmsConfig
     */
    private void handleEachItem(Item item, EmsConfig config) {
        if (EMS_IP.equals(item.getKeyName())) {
            config.setEmsIp(item.getValue());
        } else if (EMS_PORT.equals(item.getKeyName())) {
            int port = StringUtil.toInt(item.getValue(), 54351);
            config.setEmsPort(port);
        } else if (EMS_ID.equals(item.getKeyName())) {
            config.setEmsId(item.getValue());
        } else if (EMS_NAME.equals(item.getKeyName())) {
            config.setEmsName(item.getValue());
        } else if (U2K_IP.equals(item.getKeyName())) {
            config.setU2kIp(item.getValue());
        } else if (U2K_PORT.equals(item.getKeyName())) {
            int u2kPort = StringUtil.toInt(item.getValue(), 52001);
            config.setU2kPort(u2kPort);
        } else if (U2K_NAME.equals(item.getKeyName())) {
            config.setU2kName(item.getValue());
        } else if (U2K_PWD.equals(item.getKeyName())) {
            config.setU2kPwd(item.getValue());
        }
    }
}
